package Redis

import (
	user "GoDance/webserver/Entity"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"net/http"
	"time"
)

// redis

// 定义一个全局变量
var redisdb *redis.Client

func InitRedis() (err error) {
	redisdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // 用户IP地址:端口号
		Password: "",               //密码
		DB:       0,                // redis一共16个库，指定其中一个库即可
	})
	_, err = redisdb.Ping().Result()
	return
}

//存验证码
func Save_code(email string, code int) error {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return err
	}
	fmt.Println("redis连接成功！")
	// 存普通string类型，10分钟过期
	redisdb.Set(email, code, time.Minute*10)
	return nil
}

//获取验证码
func Get_code(email string) (string, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return "", err
	}
	fmt.Println("redis连接成功！")
	result := redisdb.Get(email).Val()
	return result, nil
}

//对于收藏夹功能

//删除所有的数据库 销户时的操作
func Delete_all(userId string) error {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return err
	}
	keys := redisdb.LRange(userId+":bag", 0, -1).Val()
	for _, i := range keys {
		//删除收藏夹
		_, err = Delete_Bag(userId, i)
		if err != nil {
			fmt.Printf("connect redis failed! err : %v\n", err)
			return err
		}
	}
	return nil
}

//创建一个收藏夹
func Create_Bag(userId, bagname string) (int64, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}

	//首先判断 bag中是否有这个收藏夹
	ok, err := Bag_exist_child(userId, bagname)
	if err != nil || ok != 0 {
		fmt.Printf("connect redis failed! err : %v\n", err)
		fmt.Printf("或者 已经有这个收藏夹了")
		return -1, err
	}
	//首先给bag表中增加收藏夹名
	redisdb.LPush(userId+":bag", bagname)

	//再创建一个表 用做这个收藏夹
	redisdb.HSet(userId+":"+bagname, "", "")

	return 0, nil
}

//删除一个收藏夹
func Delete_Bag(userId, bagname string) (int64, error) {

	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}

	//首先判断 bag中是否有这个收藏夹
	ok, err := Bag_exist_child(userId, bagname)
	if err != nil || ok == 0 {
		fmt.Printf("connect redis failed! err : %v\n", err)
		fmt.Printf("或者 没有这个收藏夹了")
		return -1, err
	}

	//首先给bag表中删除收藏夹名
	redisdb.LRem(userId+":bag", 1, bagname)

	//再删除这个收藏夹
	redisdb.Del(userId + ":" + bagname)

	return 0, nil
}

// 收藏夹一共多少个 每个都是啥
func Get_BagName(userId string) ([]string, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return nil, err
	}
	fmt.Println("redis连接成功！")

	result := redisdb.LRange(userId+":bag", 0, -1).Val()
	return result, nil
}

//对于收藏夹内容的操作

//增加一个内容
func Add_one(userId, bagname, key, value string) error {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return err
	}
	fmt.Println("redis连接成功！")

	//首先判断 bag中是否有这个收藏夹
	ok, err := Bag_exist_child(userId, bagname)
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		fmt.Printf("或者 没有这个收藏夹了")
		return err
	}

	//没有 先创建
	if ok == 0 {
		Create_Bag(userId, bagname)
	}

	redisdb.HSet(userId+":"+bagname, key, value)

	return nil
}

//删除一个内容
func Delete_one(userId, bagname, key string) (int64, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}
	fmt.Println("redis连接成功！")

	//首先判断 bag中是否有这个收藏夹
	ok, err := Bag_exist_child(userId, bagname)
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}

	if ok == 0 {
		fmt.Printf("或者 没有这个收藏夹了")
		return -2, nil
	}

	//判断是否有这个内容
	or := redisdb.HExists(userId+":"+bagname, key).Val()
	if or == false { //没有这个内容
		return -3, nil
	}

	redisdb.HDel(userId+":"+bagname, key)

	return 0, nil
}

//查找所有内容
func Select_all(userId, bagname string) ([]user.Collection, error) {
	err := InitRedis()
	colls := make([]user.Collection, 0)
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return nil, err
	}
	fmt.Println("redis连接成功！")

	m1, err := redisdb.HGetAll(userId + ":" + bagname).Result()
	fmt.Println("m1 len : ", len(m1))
	if err != nil {
		return nil, err
	}
	for k, v := range m1 {
		if k != "" {
			coll := user.Collection{k, v}
			colls = append(colls, coll)
		}
	}

	return colls, nil
}

//判断是否存在收藏夹 1 为存在 0 为不存在
func Bag_exist(userId string) (int64, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}
	fmt.Println("redis连接成功！")
	//判断 这个用户有没有收藏夹
	ok := redisdb.Exists(userId + ":bag").Val()
	return ok, nil
}

//判断某个收藏夹是否存在
func Bag_exist_child(userId, bagname string) (int64, error) {
	err := InitRedis()
	if err != nil {
		fmt.Printf("connect redis failed! err : %v\n", err)
		return -1, err
	}
	fmt.Println("redis连接成功！")

	ok := redisdb.Exists(userId + ":" + bagname).Val()
	return ok, nil
}

//与前端交互  获取收藏夹的名称
func Get_Collection_final() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")

		id := userId.(string)
		//判断是否存在收藏夹
		ok, err := Bag_exist(id)
		if err != nil {
			fmt.Printf("在获取收藏夹时出现错误")
			c.JSON(http.StatusNotFound, gin.H{
				"code": 404,
			})
			c.Abort()
			return
		} else if ok == 0 {
			c.JSON(http.StatusOK, gin.H{
				"code":    201,
				"message": "收藏夹为空",
			})
			c.Abort()
			return
		} else {
			names, err := Get_BagName(id)
			if err != nil {
				fmt.Printf("在获取收藏夹时出现错误")
				c.JSON(http.StatusNotFound, gin.H{
					"code": 404,
				})
				c.Abort()
				return
			}
			c.JSON(http.StatusOK, gin.H{
				"code":  200,
				"names": names,
			})
			c.Abort()
			return
		}
	}
}

func Get_Bag_Child() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")
		id := userId.(string)
		name := c.Query("name")
		child, err := Select_all(id, name)
		fmt.Println("child: ", child, len(child))
		if err != nil {
			fmt.Printf("在获取收藏夹时出现错误")
			c.JSON(http.StatusNotFound, gin.H{
				"code": 404,
			})
			c.Abort()
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code":     200,
			"children": child,
		})
	}
}

func Add_collection() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")
		id := userId.(string)
		name := c.PostForm("name")
		ok, err := Create_Bag(id, name)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{
				"code": 500,
			})
			c.Abort()
			return
		} else if ok == -1 {
			c.JSON(http.StatusOK, gin.H{
				"code": 404,
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": 200,
			})
		}
	}
}

func Delete_collection() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")
		id := userId.(string)
		name := c.PostForm("name")
		ok, err := Delete_Bag(id, name)
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{
				"code": 500,
			})
			c.Abort()
			return
		} else if ok == -1 {
			c.JSON(http.StatusOK, gin.H{
				"code": 404,
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": 200,
			})
		}
	}
}

func Add_child() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")
		id := userId.(string)
		name := c.PostForm("name")
		title := c.PostForm("title")
		href := c.PostForm("href")
		err := Add_one(id, name, title, href)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 500,
			})
			c.Abort()
			return
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": 200,
			})
		}
	}
}

func Delete_child() func(c *gin.Context) {
	return func(c *gin.Context) {
		userId, _ := c.Get("userId")
		id := userId.(string)
		name := c.PostForm("name")
		title := c.PostForm("title")
		ok, err := Delete_one(id, name, title)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 500,
			})
		} else if ok == -3 {
			c.JSON(http.StatusOK, gin.H{
				"code": 405,
			})
		} else if ok == -2 {
			c.JSON(http.StatusOK, gin.H{
				"code": 404,
			})
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": 200,
			})
		}
	}
}

//判断是否被收藏
func Is_not() func(c *gin.Context) {
	return func(c *gin.Context) {
		userid, _ := c.Get("userId")
		Id := c.PostForm("id")
		boolean := 0
		names, _ := Get_BagName(userid.(string))

		title := ""
		bagname := ""
		for i := 0; i < len(names); i++ {
			users, _ := Select_all(userid.(string), names[i])
			for j := 0; j < len(users); j++ {
				if users[j].Href == Id {
					boolean = 1
					title = users[j].Title
					bagname = names[i]
				}
			}
		}

		c.JSON(http.StatusOK, gin.H{
			"code":   200,
			"is_not": boolean,
			"name":   bagname,
			"title":  title,
		})
	}
}

func main() {

	/*userid := "方逸达"*/
	//判断收藏夹是否存在  1存在 0 不存在
	/*ok, err := Bag_exist(userid)
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}
	fmt.Println(ok)*/

	//创建收藏夹
	/*err := Create_Bag(userid, "青训营")
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}*/

	//再次测试收藏夹是否存在
	/*ok, err = Bag_exist(userid)
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}
	fmt.Println(ok)*/

	//给收藏夹增加数据
	/*err = Add_one(userid, "青训营", "百度", "www.baidu.com")
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}*/

	//给收藏夹删除数据
	/*err = Delete_one(userid, "青训营", "百度")
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}*/

	//删除数据夹
	/*err = Delete_Bag(userid, "青训营")
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}*/
	/*userid := "110"
	err := Create_Bag(userid, "青训营")
	if err != nil {
		fmt.Printf("%#v\n", err)
		return
	}*/

	/*Delete_all("110")*/
}
